package com.lxh.lxhcrm.model.service;

import com.alibaba.fastjson.JSONObject;
import com.lxh.lxhcrm.model.dao.ddic.ConClassifyDao;
import com.lxh.lxhcrm.model.dao.ddic.ConStateDao;
import com.lxh.lxhcrm.model.dao.ddic.PayMethodDao;
import com.lxh.lxhcrm.model.dao.ddic.PaymentMethodDao;
import com.lxh.lxhcrm.model.dao.inSale.*;
import com.lxh.lxhcrm.model.mappers.inSale.ContractMapper;
import com.lxh.lxhcrm.model.mappers.inSale.ProductListMapper;
import com.lxh.lxhcrm.model.pojos.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * 开发团队 ：lxh
 * @author ：鞠玮
 * 开发时间 ：2020/1/9 10:35
 * 类的名称 ：InSaleService
 * 类的描述 ：售中模块service类，所有业务逻辑都在此
 */
@Service
@Transactional
public class InSaleService {
    @Resource
    ContractMapper cm;
    @Resource
    ContractDao cd;
    @Resource
    ConClassifyDao conClassifyDao;
    @Resource
    ConStateDao conStateDao;
    @Resource
    PaymentMethodDao paymentMethodDao;
    @Resource
    PayMethodDao payMethodDao;
    @Resource
    ProductListDao productListDao;
    @Resource
    ProductListMapper productListMapper;
    @Resource
    DeliveryPlanDao deliveryPlanDao;
    @Resource
    DeliveryProListDao deliveryProListDao;
    @Resource
    DeliveryRecordDao deliveryRecordDao;
    @Resource
    ReturnmonDao returnmonDao;
    @Resource
    ReturnRecordDao returnRecordDao;
    @Resource
    ConInvoiceRecordDao conInvoiceRecordDao;
    @Resource
    CustomerService customerService;


    /**
     * 根据合同id查询开票记录
     * @param contractId 合同id
     * @return  回款计划列表
     */
    public List<ConInvoiceRecord> findConInvoiceRecordByContractId(Integer contractId){
        return cm.findConInvoiceRecordByContractId(contractId);
    }

    /**
     * 获取最新的五条数据
     * @return List<Contract> 合同集合
     */
    public List<Contract> findContractLast() {
        return cm.findContractLast();
    }

    /**
     * 根据合同id查询回款记录
     * @param contractId 合同id
     * @return  回款计划列表
     */
    public List<ReturnRecord> findAllReturnRecordByContractId(Integer contractId){
        return cm.findAllReturnRecordByContractId(contractId);
    }

    /**
     * 根据合同编号查找回款计划
     * @param contractId 合同编号
     * @return  List<Returnmon> 回款计划列表
     */
    public List<Returnmon> queryReturnMonBycontractId(Integer contractId) {
        return cm.findAllReturnmonByContractId(contractId);
    }

    /**
     * 查询回款计划中未回款的且设置提醒
     * @return List<Returnmon>
     */
    public List<Returnmon> findAllReturnmonNotReturn() {
        return cm.findAllReturnmonNotReturn();
    }

    /**
     * 根据合同编号查询交付记录
     * @param contractId 合同编号
     * @return List<DelRecord> 交付计划集合
     */
    public List<DelRecord> queryDeliveryRecordByContractId(Integer contractId){
        return cm.findDelRecordByContractId(contractId);
    }

    /**
     * 添加交付记录
     */
    public void saveDeliveryRecord(DelRecord dr){
        // 新增或修改交付记录
        deliveryRecordDao.save(dr);
        Contract contract = dr.getDeliveryPlan().getContract();
        if (contract.getConState().getId() == 2){
            ConState conState = new ConState();
            conState.setId(3);
            contract.setConState(conState);
            saveContract(contract);
        }
        // 修改交付产品
        dr.getDeliveryPlan().getDeliveryProLists().forEach(deliveryProList -> {
            // 将交付计划对象放入产品中
            deliveryProList.setDeliveryPlan(dr.getDeliveryPlan());
            deliveryProListDao.save(deliveryProList);
        });

    }
    /**
     * 添加交付计划
     */
    public void addDelivery(DeliveryPlan deliveryPlan){
        // 执行交付计划的新增
        DeliveryPlan newDeliveryPlan = deliveryPlanDao.save(deliveryPlan);
        // 获取计划中的产品列表
        List<DeliveryProList> dpls = deliveryPlan.getDeliveryProLists();
        dpls.forEach(dpl -> {
            dpl.setDeliveryPlan(newDeliveryPlan);
            deliveryProListDao.save(dpl);
        });
    }

    /**
     * 获取所有的合同
     * @return List<Map<String,Object>>
     */
    public List<Contract> findAllContract(Integer state, String search, String searchBy){
        return cm.findAllContract(state, search, searchBy);
    }

    /**
     * 根据合同id获取合同
     * @param contractId 合同id
     * @return Contract 合同对象
     */
    public Contract findContractById(Integer contractId){
        return cm.findContractById(contractId);
    }

    /**
     * 获取保存合同页面时候的初始化数据
     * @return JSONObject:初始化的数据集合对象
     */
    public JSONObject saveInitData() {
        JSONObject json = new JSONObject();
        // 付款方式
        List<PaymentMethod> paymentMethods = paymentMethodDao.findByIsOn(1);
        // 合同状态
        List<ConState> conStates = conStateDao.findByIsOn(1);
        // 结款方式
        List<PayMethod> payMethods = payMethodDao.findByIsOn(1);
        // 合同分类
        List<ConClassify> conClassifies = conClassifyDao.findByIsOn(1);
        // 将数据存入JSON对象中
        json.put("paymentMethods", paymentMethods);
        json.put("conStates", conStates);
        json.put("payMethods", payMethods);
        json.put("conClassifies", conClassifies);
        return json;
    }

    /**
     * 合同的新增和修改
     */
    public void saveContract(Contract contract) {
        /* 更新前的合同对象，初始化 */
        Contract oldContracte = null;
        List<Integer> listId = new ArrayList();
        // 保存合同
        Contract con = cd.save(contract);
        /* 如果执行的是更新则获取之前合同对象 */
        if (contract.getContractId() != 0) {
            oldContracte = cd.findById(contract.getContractId()).orElse(null);
            // 获取合同中 产品的编号列表
            oldContracte.getProductList().forEach(productList -> {
                // 将产品编号存入列表
                listId.add(productList.getListId());
            });
        }
        contract.getProductList().forEach(pl -> {
            // 比对以前的合同产品中现在没有的：有的就剔除，剩下的就是没有的了
            if (listId.indexOf(pl.getListId())>=0){
                listId.remove(listId.indexOf(pl.getListId()));
            }
            pl.setContract(con);
            productListDao.save(pl);
        });
        // 删除已经不存在的产品
        for (Integer id: listId){
            productListDao.deleteById(id);
        }
        // 新增合同的时候修改客户的状态
        if(contract.getContractId() == 0){
            customerService.stageChange3(contract.getCustomer());
            customerService.stageChange4(contract.getCustomer());
        }
    }

    /**
     * 修改合同中产品列表
     */
    public void updateProductList(ProductList pl){
        productListMapper.updateProductList(pl);
    }

    /**
     * 根据合同编号查询交付计划
     * @param contractId:合同编号
     * @return List<DeliveryPlan>：交付计划集合
     */
    public List<DeliveryPlan> getDeliveries(Integer contractId) {
        return cm.findAllDeliveryByContractId(contractId);
    }

    /**
     * 根据交付计划编号删除计划
     * @param deliveryPlanId 交付计划编号
     */
    public void deleteDelivery(Integer deliveryPlanId) {
        // 删除关联产品
        deliveryProListDao.deleteByDeliveryPlan_DeliveryPlanId(deliveryPlanId);
        // 删除交付计划
        deliveryPlanDao.deleteById(deliveryPlanId);
    }

    /**
     * 保存回款计划
     * @param rn 交付计划对象
     */
    public void saveReturnMon(Returnmon rn) {
        returnmonDao.save(rn);
    }


    /**
     * 根据回款计划id删除回款计划
     * @param returnID 回款计划id
     */
    public void deleteReturnmon(Integer returnID) {
        returnmonDao.deleteById(returnID);
    }

    /**
     * 新增和修改回款记录
     * @param returnRecord 回款记录对象
     */
    public void saveReturnRecord(ReturnRecord returnRecord) {
        // 添加回款记录
        returnRecordDao.save(returnRecord);
        // 修改合同中的回款金额
        Contract contract = returnRecord.getContract();
        // 获取当前合同所有的回款记录，用于计算总的回款金额
        List<ReturnRecord> allReturnRecord = cm.findAllReturnRecordByContractId(contract.getContractId());
        // 计算总回款金额
        double totalMoney = allReturnRecord.stream().mapToDouble(ReturnRecord::getReturnMoney).sum();
        contract.setReturnMoney(totalMoney);
        // 判断是否已全部回款，是则修改合同状态为已回款
        if (contract.getReturnMoney() >= contract.getTotalMoney()){
            ConState conState = new ConState();
            conState.setId(4);
            contract.setConState(conState);
        }
        // 存入数据库
        cd.save(contract);
        // 修改回款计划为已回款
        Returnmon returnmon = returnRecord.getReturnmon();
        returnmon.setIsReturn(1);
        returnmon.setContract(contract);
        returnmonDao.save(returnmon);
    }
    /**
     * 新增和修改开票记录
     * @param cir 开票记录对象
     */
    public void saveConInvoice(ConInvoiceRecord cir) {
        // 修改的时候合同中的开票金额先减去原来的开票记录金额在加上现在的金额
        if (cir.getConInvoiceRecId() != 0){
            ConInvoiceRecord oldCir = conInvoiceRecordDao.findById(cir.getConInvoiceRecId()).get();
            Contract contract = cir.getContract();
            contract.setInvoiceMoney(contract.getInvoiceMoney()- oldCir.getInvMoney() + cir.getInvMoney());
            saveContract(contract);
        }
        conInvoiceRecordDao.save(cir);

    }
}
